<?php
# Interface for the RATS client library.
#
# Copyright (C) 2008 rambla.be
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

/**
 * @file
 * Implementation of the Rats interface class.
 */
 
require_once dirname(__FILE__) . '/../Raws.php';
require_once dirname(__FILE__) . '/../Util.php';
require_once dirname(__FILE__) . '/Rats/UserEntry.php';
require_once dirname(__FILE__) . '/Rats/SrcEntry.php';
require_once dirname(__FILE__) . '/Rats/SrcFeed.php';
require_once dirname(__FILE__) . '/Rats/TranscEntry.php';
require_once dirname(__FILE__) . '/Rats/TranscFeed.php';
require_once dirname(__FILE__) . '/Rats/OverlayEntry.php';
require_once dirname(__FILE__) . '/Rats/OverlayFeed.php';
require_once dirname(__FILE__) . '/Rats/JobEntry.php';
require_once dirname(__FILE__) . '/Rats/JobFeed.php';
require_once dirname(__FILE__) . '/Rats/JobQuery.php';
require_once dirname(__FILE__) . '/Rats/InputEntry.php';
require_once dirname(__FILE__) . '/Rats/InputFeed.php';
require_once dirname(__FILE__) . '/Rats/OutputEntry.php';
require_once dirname(__FILE__) . '/Rats/OutputFeed.php';
require_once dirname(__FILE__) . '/Rats/FormatEntry.php';
require_once dirname(__FILE__) . '/Rats/FormatFeed.php';
require_once dirname(__FILE__) . '/Rats/FormatQuery.php';

/**
 * Class containing interface methods for RATS API.
 **/
class Rats extends Raws
{

    public static $namespaces = array(
            'raws' => 'http://rambla.be/raws/ns-metadata/1.0');

    /**
     * Instantiate a Rats object.
     *
     * @param string $user The Rambla username.
     * @param string $pwd The Rambla pwd.
     * @param string $base_uri URI of the RATS server; use 'http://rats.enc01.rambla.be/' or leave null unless you have a custom setup.
     * @param string $path Currently not being used; leave null.
     * @param Zend_Http_Client $client Leave null, unless the caller has instantiated his own Zend_Http_Client object.
     * @param string $applicationId Identification string for your client, to be sent in the HTTP headers.
     */
    public function __construct($user = null, $pwd = null, $base_uri = null, $path = null, $client = null, $applicationId = 'MyCompany-MyApp-1.0')
    {
      if (! $base_uri) {
        $base_uri = "http://rats.enc01.rambla.be";
      }
      $this->registerPackage('Rats');
      $this->registerPackage('Rats_Extension');
      parent::__construct($user, $pwd, $base_uri, $path, $client, $applicationId);
    }
  
    /**
     * Upload a src file, creating a RATS src instance (POST /src).
     *
     * @param string $filename The filename for the src instance on the RATS server.
     * @param string $src_location Local path to the file that needs to be uploaded.
     * @return Rats_SrcEntry
     */
    public function createSrc($filename, $src_location)
    {
      // Set the URI to which the file will be uploaded.
      $base_uri = $this->getBaseUri();
      $uri = safe_raws_uri($base_uri, "src", "");
      
      // Create the media source which describes the file.
      require_once "Zend/Gdata/App/MediaFileSource.php";
      $src = new Zend_Gdata_App_MediaFileSource($src_location);

      # handle the slug header, send POST request, and remove slug header again
      try {
        $src->setSlug($filename);
        $response = $this->post($src, $uri, null, "video/*");
      }
      catch(Zend_Gdata_App_Exception $e) {
        $this->unsetSlugHeader();
        throw $e;
      }
      $this->unsetSlugHeader();

      if ($response->isSuccessful()) {
        $returnEntry = new Rats_SrcEntry($response->getBody());
        $returnEntry->setHttpClient(self::getstaticHttpClient());
        return $returnEntry;
      }
      return $response;
    }

    /**
     * Retrieve an existing src entry (GET /src/{username}/{filename}).
     *
     * @param string $uri The URI that is pointing to the src instance.
     * @return Rats_SrcEntry
     */
    public function getSrcEntry($uri)
    {
      return parent::getEntry($uri, 'Rats_SrcEntry');
    }    
    
    /**
     * Retrieve an existing src entry (GET /src/{username}/{filename}).
     *
     * @param string $filename The src filename, by which it is known on the RATS server.
     * @return Rats_SrcEntry
     */
    public function getSrcEntryFromFilename($filename)
    {
      $src_path = $this->getUser() . "/" . $filename;
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "src", $src_path);
      return parent::getEntry($uri, 'Rats_SrcEntry');
    }    

    /**
     * Retrieve a feed of existing src entries (GET /src).
     *
     * @param Rats_SrcQuery $query A Rats_SrcQuery that allows passing query-string parameters.
     * @return Rats_SrcFeed
     */
    public function getSrcFeed($query = null)
    {
      $resource = "src";
      if ($query) {
        # let the query-obj compose the uri, when present
        $uri = $query->getQueryUrl($this->getBaseUri());
      }
      else {
        # no query obj, compose URI without query-string
        $uri = safe_raws_uri($this->getBaseUri(), $resource);
      }
      return parent::getFeed($uri, 'Rats_SrcFeed');
    }

    /**
     * Delete an existing src entry (DELETE /src/{username}/{filename}).
     *
     * @param string $uri The URI that is pointing to the src instance.
     */
    public function deleteSrc($uri)
    {
      $this->delete($uri);
    }
  
    /**
     * Delete an existing src entry (DELETE /src/{username}/{filename}).
     *
     * @param string $filename The src filename, by which it is known on the RATS server.
     */
    public function deleteSrcFromFilename($filename)
    {
      # URI to delete
      $uri = safe_raws_uri($this->getBaseUri(), "src", $this->getUser() . "/" . $filename);
      $this->delete($uri);
    }
    
    
    
    
    /**
     * Retrieve an existing transc entry (GET /transc/{username}/{filename}).
     *
     * @param string $uri The URI that is pointing to the transc instance.
     * @return Rats_TranscEntry
     */
    public function getTranscEntry($uri)
    {
      return parent::getEntry($uri, 'Rats_TranscEntry');
    }    
    
    /**
     * Retrieve a feed of existing transc entries (GET /transc).
     *
     * @param Rats_TranscQuery $query A Rats_TranscQuery that allows passing query-string parameters.
     * @return Rats_TranscFeed
     */
    public function getTranscFeed($query = null)
    {
      $resource = "transc";
      if ($query) {
        # let the query-obj compose the uri, when present
        $uri = $query->getQueryUrl($this->getBaseUri());
      }
      else {
        # no query obj, compose URI without query-string
        $uri = safe_raws_uri($this->getBaseUri(), $resource);
      }
      return parent::getFeed($uri, 'Rats_TranscFeed');
    }

    /**
     * Delete an existing transc entry (DELETE /transc/{username}/{filename}).
     *
     * @param string $uri The URI that is pointing to the transc instance.
     */
    public function deleteTransc($uri)
    {
      $this->delete($uri);
    }
  
    /**
     * Delete an existing transc entry (DELETE /transc/{username}/{filename}).
     *
     * @param string $filename The transc filename, by which it is known on the RATS server.
     */
    public function deleteTranscFromFilename($filename)
    {
      # URI to delete
      $uri = safe_raws_uri($this->getBaseUri(), "transc", $this->getUser() . "/" . $filename);
      $this->delete($uri);
    }

    

  /**
   * Upload a overlay file, creating a RATS overlay instance (POST /overlay).
   *
   * @param string $filename The filename for the overlay instance on the RATS server.
   * @param string $overlay_location Local path to the file that needs to be uploaded.
   * @return Rats_OverlayEntry
   */
  public function createOverlay($filename, $overlay_location)
  {
    // Set the URI to which the file will be uploaded.
    $base_uri = $this->getBaseUri();
    $uri = safe_raws_uri($base_uri, "overlay", "");
    
    // Create the media source which describes the file.
    require_once "Zend/Gdata/App/MediaFileSource.php";
    
    $overlay = new Zend_Gdata_App_MediaFileSource($overlay_location);

    # handle the slug header, send POST request, and remove slug header again
    try {
      $overlay->setSlug($filename);
      $response = $this->post($overlay, $uri, null, "image/*");
    }
    catch(Zend_Gdata_App_Exception $e) {
      $this->unsetSlugHeader();
      throw $e;
    }
    $this->unsetSlugHeader();

    if ($response->isSuccessful()) {
      $returnEntry = new Rats_OverlayEntry($response->getBody());
      $returnEntry->setHttpClient(self::getstaticHttpClient());
      return $returnEntry;
    }
    return $response;
  }

  /**
   * Retrieve an existing overlay entry (GET /overlay/{username}/{filename}).
   *
   * @param string $uri The URI that is pointing to the overlay instance.
   * @return Rats_OverlayEntry
   */
  public function getOverlayEntry($uri)
  {
    return parent::getEntry($uri, 'Rats_OverlayEntry');
  }    
    
  /**
   * Retrieve an existing overlay entry (GET /overlay/{id}).
   *
   * @param string $id The overlay's ID on the RATS server.
   * @return Rats_OverlayEntry
   */
  public function getOverlayEntryFromId($id)
  {
    # user can only update herself, so set the path right
    $uri = safe_raws_uri($this->getBaseUri(), "overlay", $id);
    return parent::getEntry($uri, 'Rats_OverlayEntry');
  }
      
  /**
   * Retrieve a feed of existing overlay entries (GET /overlay).
   *
   * @param Rats_OverlayQuery $query A Rats_OverlayQuery that allows passing query-string parameters.
   * @return Rats_OverlayFeed
   */
  public function getOverlayFeed($query = null)
  {
    $resource = "overlay";
    if ($query) {
      # let the query-obj compose the uri, when present
      $uri = $query->getQueryUrl($this->getBaseUri());
    }
    else {
      # no query obj, compose URI without query-string
      $uri = safe_raws_uri($this->getBaseUri(), $resource);
    }
    return parent::getFeed($uri, 'Rats_OverlayFeed');
  }

  /**
   * Delete an existing overlay entry (DELETE /overlay/{username}/{id}).
   *
   * @param string $uri The URI that is pointing to the overlay instance.
   */
  public function deleteOverlay($uri)
  {
    $this->delete($uri);
  }

  /**
   * Delete an existing src entry (DELETE /overlay/{username}/{id}).
   *
   * @param string $id The overlay ID.
   */
  public function deleteOverlayFromId($id)
  {
    # user can only update herself, so set the path right
    $uri = safe_raws_uri($this->getBaseUri(), "overlay", $id);
    $this->delete($uri);
  }
    
  
    /**
     * Launch a new transcoding job, by creating a new RATS job instance (POST /job).
     * This method is deprecated since RATS v1.40, preferably use createJobForExistingSrc() or createJobForImportSrc() instead.
     *
     * @param string $input ID of the input profile or null.
     * @param string $output ID of the output profile or null.
     * @param string $format ID of the transcoding format profile.
     * @param string $src_location Filename of an existing src (if applicable).
     * @param string $tgt_location Filename to be given to the transcoded file.
     * @param string $startpos Offset in seconds from the beginning of the src file, where transcoding must start.
     * @param string $endpos Offset in seconds from the end of the src file, where transcoding must end.
     * @param string $client_passthru Placeholder for data to receive back in the job's report.
     * @param string $client_input Custom data to be sent to RATS.
     * @param string $import_location Path to a src file that needs to be imported (if applicable).
     * @param string $proc Processing action to be done as part of the job (optional).
     * @return Rats_JobEntry
     */
    public function createJob($input, $output, $format, $src_location = null, $tgt_location = null, $startpos = null, $endpos = null, $client_passthru = null, $client_input = null, $import_location = null, $proc = null)
    {
      # URI to post to
      $uri = safe_raws_uri($this->getBaseUri(), "job");
      // Create a new entry object (short notation for: $newEntry = new Rats_JobEntry();)
      $newEntry = $this->newJobEntry();
      // Create a new jobParams object (short notation for: $newParams = new Rats_Extension_Params();)
      $newParams = $this->newJobParams();
      $newParams->input = $this->newInput($input);
      $newParams->output = $this->newOutput($output);
      $newParams->format = $this->newFormat($format);
      $newParams->src_location = $this->newSrcLocation($src_location);
      $newParams->import_location = $this->newImportLocation($import_location);
      $newParams->tgt_location = $this->newTgtLocation($tgt_location);
      $newParams->startpos = $this->newStartpos($startpos);
      $newParams->endpos = $this->newEndpos($endpos);
      $newParams->client_passthru = $this->newClientPassthru($client_passthru);
      $newParams->client_input = $this->newClientInput($client_input);
      $newParams->proc = $this->newProc($proc);
      
      # Create a new jobContent object and set it on the entry
      $newEntry->content = $this->newJobContent($newParams);
      # Call app's insertEntry() to send it to the server
      return $this->insertEntry($newEntry, $uri, 'Rats_JobEntry');
    }
    
    
    /**
     * Launch a new transcoding job, by creating a new RATS job instance (POST /job) for a src present on the RATS server.
     *
     * @param string $output ID of the output profile or null.
     * @param string $format ID of the transcoding format profile.
     * @param string $src_location Filename of an existing src (if applicable).
     * @param string $tgt_location Filename to be given to the transcoded file.
     * @param string $startpos Offset in seconds from the beginning of the src file, where transcoding must start.
     * @param string $endpos Offset in seconds from the end of the src file, where transcoding must end.
     * @param string $video_bitrate Overrides format setting.
     * @param string $audio_bitrate Overrides format setting.
     * @param string $client_passthru Placeholder for data to receive back in the job's report.
     * @param string $client_input Custom data to be sent to RATS.
     * @param string $proc Processing action to be done as part of the job (optional).
     * @param string $video_height Overrides format setting.
     * @param string $video_width Overrides format setting.
     * @return Rats_JobEntry
     */
    public function createJobForExistingSrc($output, $format, $src_location, $tgt_location = null, $startpos = null, $endpos = null, $video_bitrate = null, 
                                            $audio_bitrate = null, $client_passthru = null, $client_input = null, $proc = null,
                                            $video_height = null, $video_width = null)
    {
      # URI to post to
      $uri = safe_raws_uri($this->getBaseUri(), "job");
      // Create a new entry object (short notation for: $newEntry = new Rats_JobEntry();)
      $newEntry = $this->newJobEntry();
      // Create a new jobParams object (short notation for: $newParams = new Rats_Extension_Params();)
      $newParams = $this->newJobParams();
      $newParams->output = $this->newOutput($output);
      $newParams->format = $this->newFormat($format);
      $newParams->src_location = $this->newSrcLocation($src_location);
      $newParams->tgt_location = $this->newTgtLocation($tgt_location);
      $newParams->startpos = $this->newStartpos($startpos);
      $newParams->endpos = $this->newEndpos($endpos);
      $newParams->video_bitrate = $this->newVideoBitrate($video_bitrate);
      $newParams->audio_bitrate = $this->newAudioBitrate($audio_bitrate);
      $newParams->video_height = $this->newVideoHeight($video_height);
      $newParams->video_width = $this->newVideoWidth($video_width);
      $newParams->client_passthru = $this->newClientPassthru($client_passthru);
      $newParams->client_input = $this->newClientInput($client_input);
      $newParams->proc = $this->newProc($proc);
      
      # Create a new jobContent object and set it on the entry
      $newEntry->content = $this->newJobContent($newParams);
      # Call app's insertEntry() to send it to the server
      return $this->insertEntry($newEntry, $uri, 'Rats_JobEntry');
    }


    /**
     * Launch a new transcoding job, by creating a new RATS job instance (POST /job) for a src that needs to be imported first.
     *
     * @param string $input ID of the input profile or null.
     * @param string $output ID of the output profile or null.
     * @param string $format ID of the transcoding format profile.
     * @param string $import_location Path to a src file that needs to be imported (if applicable).
     * @param string $tgt_location Filename to be given to the transcoded file.
     * @param string $startpos Offset in seconds from the beginning of the src file, where transcoding must start.
     * @param string $endpos Offset in seconds from the end of the src file, where transcoding must end.
     * @param string $video_bitrate Overrides format setting.
     * @param string $audio_bitrate Overrides format setting.
     * @param string $client_passthru Placeholder for data to receive back in the job's report.
     * @param string $client_input Custom data to be sent to RATS.
     * @param string $proc Processing action to be done as part of the job (optional).
     * @param string $video_height Overrides format setting.
     * @param string $video_width Overrides format setting.
     * @return Rats_JobEntry
     */
    public function createJobForImportSrc($input, $output, $format, $import_location, $tgt_location = null, $startpos = null, $endpos = null, $video_bitrate = null, 
                                            $audio_bitrate = null, $client_passthru = null, $client_input = null, $proc = null,
                                            $video_height = null, $video_width = null)
    {
      # URI to post to
      $uri = safe_raws_uri($this->getBaseUri(), "job");
      // Create a new entry object (short notation for: $newEntry = new Rats_JobEntry();)
      $newEntry = $this->newJobEntry();
      // Create a new jobParams object (short notation for: $newParams = new Rats_Extension_Params();)
      $newParams = $this->newJobParams();
      $newParams->input = $this->newInput($input);
      $newParams->output = $this->newOutput($output);
      $newParams->format = $this->newFormat($format);
      $newParams->import_location = $this->newImportLocation($import_location);
      $newParams->tgt_location = $this->newTgtLocation($tgt_location);
      $newParams->video_bitrate = $this->newVideoBitrate($video_bitrate);
      $newParams->audio_bitrate = $this->newAudioBitrate($audio_bitrate);
      $newParams->video_height = $this->newVideoHeight($video_height);
      $newParams->video_width = $this->newVideoWidth($video_width);
      $newParams->startpos = $this->newStartpos($startpos);
      $newParams->endpos = $this->newEndpos($endpos);
      $newParams->client_passthru = $this->newClientPassthru($client_passthru);
      $newParams->client_input = $this->newClientInput($client_input);
      $newParams->proc = $this->newProc($proc);
    
      # Create a new jobContent object and set it on the entry
      $newEntry->content = $this->newJobContent($newParams);
      # Call app's insertEntry() to send it to the server
      return $this->insertEntry($newEntry, $uri, 'Rats_JobEntry');
    }

    /**
     * Retrieve an existing job entry (GET /job/{id}).
     *
     * @param string $uri The URI that is pointing to the job instance.
     * @return Rats_JobEntry
     */
    public function getJobEntry($uri)
    {
      return parent::getEntry($uri, 'Rats_JobEntry');
    }
   
    /**
     * Retrieve an existing job entry (GET /job/{id}).
     *
     * @param string $id The job's ID on the RATS server.
     * @return Rats_JobEntry
     */
    public function getJobEntryFromId($id)
    {
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "job", $id);
      return parent::getEntry($uri, 'Rats_JobEntry');
    }

    /**
      * Retrieve a feed of existing job entries (GET /job).
     *
     * @param Rats_JobQuery $query A Rats_JobQuery that allows passing query-string parameters.
     * @return Rats_JobFeed
     */
    public function getJobFeed($query = null)
    {
      $resource = "job";
      if ($query) {
        # let the query-obj compose the uri, when present
        $uri = $query->getQueryUrl($this->getBaseUri());
      }
      else {
        # no query obj, compose URI without query-string
        $uri = safe_raws_uri($this->getBaseUri(), $resource);
      }
      return parent::getFeed($uri, 'Rats_JobFeed');
    }
    
    
    /**
     * Launch a new transcoding input, by creating a new RATS input instance (POST /input).
     *
     * @param string $name Unique name for this profile.
     * @param string $description Description of what the profile does.
     * @param string $method One of the input methods (eg. rass, ftp).
     * @param string $base_uri : Base URI to which the job's filename or target location must be added when determining the export location (if applicable)
     * @param string $cdn the name of the Rambla CDN to export to (if applicable)
     * @param string $max_size maximum size allowed for source files (in Mb)
     * @param string $params Additional params to be sent to the export daemon.
     * @return Rats_InputEntry
     */
    public function createInput($name, $description, $method, $cdn = null, $base_uri = null, $max_size = null, $params = null)
    {
      # URI to post to
      $uri = safe_raws_uri($this->getBaseUri(), "input");
      // Create a new entry object (short notation for: $newEntry = new Rats_InputEntry();)
      $newEntry = $this->newInputEntry();
      // Create a new inputParams object (short notation for: $newParams = new Rats_Extension_Params();)
      $newParams = $this->newInputParams();
      $newParams->name = $this->newName($name);
      $newParams->description = $this->newDescription($description);
      $newParams->method = $this->newMethod($method);
      $newParams->base_uri = $this->newBaseUri($base_uri);
      $newParams->cdn = $this->newCdn($cdn);
      $newParams->max_size = $this->newMaxSize($max_size);
      $newParams->params = $this->newParams($params);
      
      # Create a new inputContent object and set it on the entry
      $newEntry->content = $this->newInputContent($newParams);
      # Call app's insertEntry() to send it to the server
      return $this->insertEntry($newEntry, $uri, 'Rats_InputEntry');
    }    

    /**
     * Retrieve an existing input entry (GET /input/{id}).
     *
     * @param string $uri The URI that is pointing to the input instance.
     * @return Rats_InputEntry
     */
    public function getInputEntry($uri)
    {
      return parent::getEntry($uri, 'Rats_InputEntry');
    }
   
    /**
     * Retrieve an existing input entry (GET /input/{id}).
     *
     * @param string $id The input's ID on the RATS server.
     * @return Rats_InputEntry
     */
    public function getInputEntryFromId($id)
    {
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "input", $id);
      return parent::getEntry($uri, 'Rats_InputEntry');
    }

    /**
      * Retrieve a feed of existing input entries (GET /input).
     *
     * @param Rats_InputQuery $query A Rats_InputQuery that allows passing query-string parameters.
     * @return Rats_InputFeed
     */
    public function getInputFeed($query = null)
    {
      $resource = "input";
      if ($query) {
        # let the query-obj compose the uri, when present
        $uri = $query->getQueryUrl($this->getBaseUri());
      }
      else {
        # no query obj, compose URI without query-string
        $uri = safe_raws_uri($this->getBaseUri(), $resource);
      }
      return parent::getFeed($uri, 'Rats_InputFeed');
    }
    
    /**
     * Delete an existing input profile.
     *
     * @param string $uri The URI that is pointing to the input instance.
     */
    public function deleteInput($uri)
    {
      $this->delete($uri);
    }

    /**
     * Delete an existing input profile.
     *
     * @param string $id The input ID.
     */
    public function deleteInputFromId($id)
    {
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "input", $id);
      $this->delete($uri);
    }
    
    
    
    

    /**
     * Launch a new transcoding output, by creating a new RATS output instance (POST /output).
     *
     * @param string $name Unique name for this profile.
     * @param string $description Description of what the profile does.
     * @param string $method One of the output methods (eg. rass, ftp).
     * @param string $base_uri : Base URI to which the job's filename or target location must be added when determining the export location (if applicable)
     * @param string $public_uri Base URI to which the job's filename or target location needs to be added when determining the final http location, at which the file will be available after export (if applicable).
     * @param string $cdn the name of the Rambla CDN to export to (if applicable)
     * @param string $max_size maximum size allowed for source files (in Mb)
     * @param string $params Additional params to be sent to the export daemon.
     * @return Rats_OutputEntry
     */
    public function createOutput($name, $description, $method, $cdn = null, $base_uri = null, $public_uri = null, $max_size = null, $params = null)
    {
      # URI to post to
      $uri = safe_raws_uri($this->getBaseUri(), "output");
      // Create a new entry object (short notation for: $newEntry = new Rats_OutputEntry();)
      $newEntry = $this->newOutputEntry();
      // Create a new outputParams object (short notation for: $newParams = new Rats_Extension_Params();)
      $newParams = $this->newOutputParams();
      $newParams->name = $this->newName($name);
      $newParams->description = $this->newDescription($description);
      $newParams->method = $this->newMethod($method);
      $newParams->base_uri = $this->newBaseUri($base_uri);
      $newParams->public_uri = $this->newPublicUri($public_uri);
      $newParams->cdn = $this->newCdn($cdn);
      $newParams->max_size = $this->newMaxSize($max_size);
      $newParams->params = $this->newParams($params);
      
      # Create a new outputContent object and set it on the entry
      $newEntry->content = $this->newOutputContent($newParams);
      # Call app's insertEntry() to send it to the server
      return $this->insertEntry($newEntry, $uri, 'Rats_OutputEntry');
    }    

    /**
     * Retrieve an existing output entry (GET /output/{id}).
     *
     * @param string $uri The URI that is pointing to the output instance.
     * @return Rats_OutputEntry
     */
    public function getOutputEntry($uri)
    {
      return parent::getEntry($uri, 'Rats_OutputEntry');
    }
   
    /**
     * Retrieve an existing output entry (GET /output/{id}).
     *
     * @param string $id The output's ID on the RATS server.
     * @return Rats_OutputEntry
     */
    public function getOutputEntryFromId($id)
    {
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "output", $id);
      return parent::getEntry($uri, 'Rats_OutputEntry');
    }

    /**
      * Retrieve a feed of existing output entries (GET /output).
     *
     * @param Rats_OutputQuery $query A Rats_OutputQuery that allows passing query-string parameters.
     * @return Rats_OutputFeed
     */
    public function getOutputFeed($query = null)
    {
      $resource = "output";
      if ($query) {
        # let the query-obj compose the uri, when present
        $uri = $query->getQueryUrl($this->getBaseUri());
      }
      else {
        # no query obj, compose URI without query-string
        $uri = safe_raws_uri($this->getBaseUri(), $resource);
      }
      return parent::getFeed($uri, 'Rats_OutputFeed');
    }
    
    /**
     * Delete an existing output profile.
     *
     * @param string $uri The URI that is pointing to the output instance.
     */
    public function deleteOutput($uri)
    {
      $this->delete($uri);
    }

    /**
     * Delete an existing output profile.
     *
     * @param string $id The output ID.
     */
    public function deleteOutputFromId($id)
    {
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "output", $id);
      $this->delete($uri);
    }
    
    


    /**
     * Launch a new transcoding format, by creating a new RATS format instance (POST /format).
     *
     * @param string $name Unique name for this profile.
     * @param string $description Description of what the profile does.
     * @param string $container : Container being used for this format.
     * @param string $category : 'formats' or 'devices'
     * @param array $video_params : Associative array of video parameters (key = param name, value = string containing the param data)
     * @param array $audio_params : Associative array of audio parameters (key = param name, value = string containing the param data)
     * @param int $hinting : 1 or 0
     * @param string $input : ID of an input profile attached to this format.
     * @param string $output : ID of an output profile attached to this format.
     * @param string $overlay : ID of an overlay profile to be used for this format.
     * @return Rats_FormatEntry
     */
    public function createFormat($name, $description, $container, $category = "formats", $video_params = array(), $audio_params = array(), $hinting = 0, $input = null, $output = null, $overlay = null)
    {
      # URI to post to
      $uri = safe_raws_uri($this->getBaseUri(), "format");
      // Create a new entry object (short notation for: $newEntry = new Rats_FormatEntry();)
      $newEntry = $this->newFormatEntry();
      // Create a new formatParams object (short notation for: $newParams = new Rats_Extension_Params();)
      $newParams = $this->newFormatParams();
      $newParams->name = $this->newName($name);
      $newParams->description = $this->newDescription($description);
      $newParams->container = $this->newContainer($container);
      $newParams->category = $this->newCategory($category);

      $newParams->hinting = $this->newHinting($hinting);
      $newParams->input = $this->newInput($input);
      $newParams->output = $this->newOutput($output);
      $newParams->overlay = $this->newOverlay($overlay);
      
      foreach ($video_params as $key => $value) {
        switch($key) {
          case "video_codec":
            $newParams->video_codec = $this->newVideoCodec($value);
            break;
          case "video_bitrate":
            $newParams->video_bitrate = $this->newVideoBitrate($value);
            break;
          case "video_fps":
            $newParams->video_fps = $this->newVideoFps($value);
            break;
          case "video_width":
            $newParams->video_width = $this->newVideoWidth($value);
            break;
          case "video_height":
            $newParams->video_height = $this->newVideoHeight($value);
            break;
          case "video_deinterlace":
            $newParams->video_deinterlace = $this->newVideoDeinterlace($value);
            break;
          case "video_cq":
            $newParams->video_cq = $this->newVideoCq($value);
            break;
          case "video_passes":
            $newParams->video_passes = $this->newVideoPasses($value);
            break;
          case "video_crop_top":
            $newParams->video_crop_top = $this->newVideoCropTop($value);
            break;
          case "video_crop_bottom":
            $newParams->video_crop_bottom = $this->newVideoCropBottom($value);
            break;
          case "video_crop_right":
            $newParams->video_crop_right = $this->newVideoCropRight($value);
            break;
          case "video_crop_left":
            $newParams->video_crop_left = $this->newVideoCropLeft($value);
            break;
        }
      }
      foreach ($audio_params as $key => $value) {
        switch($key) {
          case "audio_channel":
            $newParams->audio_channel = $this->newAudioChannel($value);
            break;
          case "audio_codec":
            $newParams->audio_codec = $this->newAudioCodec($value);
            break;
          case "audio_bitrate":
            $newParams->audio_bitrate = $this->newAudioBitrate($value);
            break;
          case "audio_sample_rate":
            $newParams->audio_sample_rate = $this->newAudioSampleRate($value);
            break;
          case "audio_passes":
            $newParams->audio_passes = $this->newAudioPasses($value);
            break;
          case "audio_track_mapping":
            $newParams->audio_track_mapping = $this->newAudioTrackMapping($value);
            break;
        }
      }

      # Create a new formatContent object and set it on the entry
      $newEntry->content = $this->newFormatContent($newParams);
      # Call app's insertEntry() to send it to the server
      return $this->insertEntry($newEntry, $uri, 'Rats_FormatEntry');
    }    

    /**
     * Retrieve an existing format entry (GET /format/{id}).
     *
     * @param string $uri The URI that is pointing to the format instance.
     * @return Rats_FormatEntry
     */
    public function getFormatEntry($uri)
    {
      return parent::getEntry($uri, 'Rats_FormatEntry');
    }
   
    /**
     * Retrieve an existing format entry (GET /format/{id}).
     *
     * @param string $id The format's ID on the RATS server.
     * @return Rats_FormatEntry
     */
    public function getFormatEntryFromId($id)
    {
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "format", $id);
      return parent::getEntry($uri, 'Rats_FormatEntry');
    }

    /**
     * Retrieve a feed of existing format entries (GET /format).
     *
     * @param Rats_FormatQuery $query A Rats_FormatQuery that allows passing query-string parameters.
     * @return Rats_FormatFeed
     */
    public function getFormatFeed($query = null)
    {
      $resource = "format";
      if ($query) {
        # let the query-obj compose the uri, when present
        $uri = $query->getQueryUrl($this->getBaseUri());
      }
      else {
        # no query obj, compose URI without query-string
        $uri = safe_raws_uri($this->getBaseUri(), $resource);
      }
      return parent::getFeed($uri, 'Rats_FormatFeed');
    }
    
    /**
     * Delete an existing transcoding format.
     *
     * @param string $uri The URI that is pointing to the format instance.
     */
    public function deleteFormat($uri)
    {
      $this->delete($uri);
    }

    /**
     * Delete an existing transcoding format.
     *
     * @param string $id The format ID.
     */
    public function deleteFormatFromId($id)
    {
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "format", $id);
      $this->delete($uri);
    }
    
    /**
     * Retrieve the user profile (GET /user).
     *
     * @return Rats_UserEntry
     */
    public function getUserEntry()
    {
      # user can only update herself, so set the path right
      $uri = safe_raws_uri($this->getBaseUri(), "user", $this->getUser());
      return parent::getEntry($uri, 'Rats_UserEntry');
    }
    
    public function createUser($username, $email, $password, $rass_default_cdn = null, $rass_username = null, $rass_password = null)
    {
      # URI to post to
      $uri = safe_raws_uri($this->getBaseUri(), "user");
      // Create a new entry object (short notation for: $newEntry = new Rats_UserEntry();)
      $newEntry = $this->newUserEntry();
      // Create a new userParams object (short notation for: $newParams = new Rats_Extension_Params();)
      $newParams = $this->newUserParams();
      $newParams->username = $this->newUsername($username);
      $newParams->email = $this->newEmail($email);
      $newParams->password = $this->newPassword($password);
      $newParams->rass_default_cdn = $this->newRassDefaultCdn($rass_default_cdn);
      $newParams->rass_username = $this->newRassUsername($rass_username);
      $newParams->rass_password = $this->newRassPassword($rass_password);
      # Create a new userContent object and set it on the entry
      $newEntry->content = $this->newUserContent($newParams);
      # Call app's insertEntry() to send it to the server
      return $this->insertEntry($newEntry, $uri, 'Rats_UserEntry');
    }
    
    public function updateUserEntry($email, $firstname = null, $lastname = null)
    {
      # user can only update herself, so set the path right
      $this->setPath($this->getUser());
      # get the entry
      $entry = $this->getUserEntry();
      # change the values
      $entry->content->params->email->text = $email;
      if ($firstname) {
        $entry->content->params->firstname->text = $firstname;
      }
      if ($lastname) {
        $entry->content->params->lastname->text = $lastname;
      }
      # update the entry
      return $entry->save();
    }
    
    public function deleteUser($username)
    {
      # URI to delete
      $uri = safe_raws_uri($this->getBaseUri(), "user", $username);
      $this->delete($uri);
    }

    
}
